
#ifndef _MEMBER_BOBCDOCUMENT_H_
#define _MEMBER_BOBCDOCUMENT_H_

#include <BMap>
#include <BMesh>
#include <BCone>
#include <BCube>
#include <BCylinder>
#include <BSphere>
#include <BGeoSphere>
#include <BTube>
#include <BTorus>
#include <BSurface>
#include <BTerrain>
#include <BTextual>
#include <BBillboard>
#include <BParticle>
#include <BCapsule>
#include <BPointRestraint>
#include <BHingeRestraint>
#include <BSliderRestraint>
#include <BConearRestraint>
#include <BSixdofRestraint>
#include <BFixedRestraint>
#include <BGearRestraint>

#include <BScene>
#include <BSoftBody>

#include <BImage>
#include <BFont>
#include <BStyle>
#include <BPixmap>
#include <BMaterial>
#include <BProgram>
#include <BUniform>
#include <BScript>
#include <BSource>
#include <BSpring>
#include <BSpacer>
#include <BSonNode>
#include <BXmlNode>
#include <BLineStripe>
#include <BSplineCurve>

#include <BFile>
#include <BBuffer>
#include <BReadWrite>
#include <BApplication>
#include <BObcDocument>

#define obcdoc_member(obcdoc)		((member_BObcDocument*)((BObcDocument*)obcdoc)->_ptr)

namespace BWE
{

#pragma pack(1)
	struct Chunk
	{
		BUShort	sign = 0;
		BUInt	end = 0;
	};
#pragma pack()

	struct ChunkInfo
	{
		BUInt	begin = 0;
		BUShort	sign = 0;
		BUInt	end = 0;
	};

	class member_BObcDocument
	{
		struct AutoChunk
		{
			inline AutoChunk(member_BObcDocument* obcdoc, BUShort sign)
			{
				this->obcdoc = obcdoc;
				obcdoc->beginChunk(sign);
				this->sign = obcdoc->chunkStack.last().sign;
			}
			inline ~AutoChunk()
			{
				obcdoc->endChunk(sign);
			}
			BUShort			sign;
			member_BObcDocument* obcdoc;
		};

	public:
		member_BObcDocument(BObcDocument* obcDocument);
		~member_BObcDocument();

		void clear();

		BObject* read(const Chunk& chunk);
		bool write(const BObject* object);

		void beginChunk(BUShort sign);
		void endChunk(BUShort sign);

		bool readBeginChunk(Chunk& chunk, int end);
		bool readEndChunk(Chunk& chunk);

		BString& message();
		const BString& message() const;

		typedef bool (member_BObcDocument::* readFunc)(const Chunk&, BObject*);
		typedef bool (member_BObcDocument::* writeFunc)(const BObject*);
		inline void regist(const BString& type, SIGN sign, readFunc rf, writeFunc wf)
		{
			this->readFuncMap[type] = rf;
			this->writeFuncMap[type] = wf;
			this->typeSignMap[type] = sign;
			this->signTypeMap[sign] = type;
		}

	public://read chunk
		bool readObject(const Chunk& chunk, BObject* object);
		bool readScene(const Chunk& chunk, BScene* scene);
		bool readGroup(const Chunk& chunk, BGroup* group);
		bool readNode(const Chunk& chunk, BNode* node);
		bool readLight(const Chunk& chunk, BLight* light);
		bool readCamera(const Chunk& chunk, BCamera* camera);
		bool readBody(const Chunk& chunk, BBody* body);
		bool readSoftBody(const Chunk& chunk, BSoftBody* softBody);

		bool readRestraint(const Chunk& chunk, BRestraint* restraint);
		bool readPointRestraint(const Chunk& chunk, BPointRestraint* restraint);
		bool readHingeRestraint(const Chunk& chunk, BHingeRestraint* restraint);
		bool readSliderRestraint(const Chunk& chunk, BSliderRestraint* restraint);
		bool readConearRestraint(const Chunk& chunk, BConearRestraint* restraint);
		bool readSixdofRestraint(const Chunk& chunk, BSixdofRestraint* restraint);
		bool readFixedRestraint(const Chunk& chunk, BFixedRestraint* fixedRestraint);
		bool readGearRestraint(const Chunk& chunk, BGearRestraint* gearRestraint);

		bool readShape(const Chunk& chunk, BShape* shape);
		bool readMesh(const Chunk& chunk, BMesh* mesh);
		bool readGeometry(const Chunk& chunk, BGeometry* geometry);
		bool readTextual(const Chunk& chunk, BTextual* textual);
		bool readBillboard(const Chunk& chunk, BBillboard* billboard);
		bool readParticle(const Chunk& chunk, BParticle* particle);
		bool readElement(const Chunk& chunk, BElement* element);

		bool readCube(const Chunk& chunk, BCube* cube);
		bool readCone(const Chunk& chunk, BCone* cone);
		bool readCylinder(const Chunk& chunk, BCylinder* cylinder);
		bool readSphere(const Chunk& chunk, BSphere* sphere);
		bool readGeoSphere(const Chunk& chunk, BGeoSphere* geoSphere);
		bool readTube(const Chunk& chunk, BTube* tube);
		bool readTorus(const Chunk& chunk, BTorus* torus);
		bool readSurface(const Chunk& chunk, BSurface* surface);
		bool readTerrain(const Chunk& chunk, BTerrain* terrain);
		bool readCapsule(const Chunk& chunk, BCapsule* capsule);
		bool readLineStripe(const Chunk& chunk, BLineStripe* lineStripe);
		bool readSplineCurve(const Chunk& chunk, BSplineCurve* splineCurve);

		bool readMaterial(const Chunk& chunk, BMaterial* material);
		bool readTexture(const Chunk& chunk, BTexture* texture);
		bool readImage(const Chunk& chunk, BImage* image);
		bool readPixmap(const Chunk& chunk, BPixmap* pixmap);
		bool readProgram(const Chunk& chunk, BProgram* program);
		bool readShader(const Chunk& chunk, BShader* shader);
		bool readUniform(const Chunk& chunk, BUniform* uniform);
		bool readScript(const Chunk& chunk, BScript* script);
		bool readSource(const Chunk& chunk, BSource* source);
		bool readExp(const Chunk& chunk, BExp* exp);

		bool readSonNode(const Chunk& chunk, BSonNode* sonNode);
		bool readXmlNode(const Chunk& chunk, BXmlNode* xmlNode);

	public://write chunk.
		bool writeObject(const BObject* object);
		bool writeScene(const BScene* scene);
		bool writeGroup(const BGroup* group);
		bool writeNode(const BNode* node);
		bool writeLight(const BLight* light);
		bool writeCamera(const BCamera* camera);
		bool writeBody(const BBody* body);
		bool writeSoftBody(const BSoftBody* softBody);

		bool writeRestraint(const BRestraint* restraint);
		bool writePointRestraint(const BPointRestraint* pointRestraint);
		bool writeHingeRestraint(const BHingeRestraint* hingeRestraint);
		bool writeSliderRestraint(const BSliderRestraint* sliderRestraint);
		bool writeConearRestraint(const BConearRestraint* conearRestraint);
		bool writeSixdofRestraint(const BSixdofRestraint* sixdofRestraint);
		bool writeFixedRestraint(const BFixedRestraint* fixedRestraint);
		bool writeGearRestraint(const BGearRestraint* gearRestraint);

		bool writeShape(const BShape* shape);
		bool writeMesh(const BMesh* mesh);
		bool writeGeometry(const BGeometry* geometry);
		bool writeElement(const BElement* element);
		bool writeTextual(const BTextual* textual);
		bool writeBillboard(const BBillboard* billboard);
		bool writeParticle(const BParticle* particle);

		bool writeCube(const BCube* cube);
		bool writeCone(const BCone* cone);
		bool writeCylinder(const BCylinder* cylinder);
		bool writeSphere(const BSphere* sphere);
		bool writeGeoSphere(const BGeoSphere* geoSphere);
		bool writeTube(const BTube* tube);
		bool writeTorus(const BTorus* torus);
		bool writeSurface(const BSurface* surface);
		bool writeTerrain(const BTerrain* terrain);
		bool writeCapsule(const BCapsule* capsule);
		bool writeLineStripe(const BLineStripe* lineStripe);
		bool writeSplineCurve(const BSplineCurve* splineCurve);

		bool writeMaterial(const BMaterial* material);
		bool writeTexture(const BTexture* texture);
		bool writeImage(const BImage* image);
		bool writePixmap(const BPixmap* pixmap);
		bool writeProgram(const BProgram* program);
		bool writeShader(const BShader* shader);
		bool writeUniform(const BUniform* uniform);
		bool writeScript(const BScript* script);
		bool writeSource(const BSource* source);
		bool writeExp(const BExp* exp);

		bool writeSonNode(const BSonNode* sonNode);
		bool writeXmlNode(const BXmlNode* xmlNode);

	public:
		BObcDocument*				boss;
		BStream*					stream;
		BByteArray					buffer;
		BValue						messageValue;
		int							chunkLevel;
		BArray<ChunkInfo>			chunkStack;
		BMap<int, BObject*>			readObjectMap;
		BMap<const BObject*, int>	writeObjectMap;

		BMap<BString, BObcDocument::readChunk>		readChunkMap;
		BMap<BString, BObcDocument::writeChunk>		writeChunkMap;
		BMap<BString, readFunc>			readFuncMap;
		BMap<BString, writeFunc>		writeFuncMap;
		BMap<BString, BUShort>			typeSignMap;
		BMap<BUShort, BString>			signTypeMap;

	};

}

#endif